import datetime
from flask import request, jsonify, g
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt
from app.models import Admin, Menu, AdminLog
from app.core.extensions import db
from . import admin_blueprint


def build_menu_tree(menus, parent_id=None):
    """构建菜单树结构"""
    tree = []
    for menu in menus:
        if menu.parent_id == parent_id:
            children = build_menu_tree(menus, menu.id)
            menu_dict = menu.to_dict(include_children=False)
            if children:
                menu_dict['children'] = children
            else:
                menu_dict['children'] = []
            tree.append(menu_dict)
    return tree


@admin_blueprint.route('/menus', methods=['GET'])
@jwt_required()
def get_menus():
    """获取菜单列表"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    # 获取所有菜单并按照排序字段排序
    menus = Menu.query.order_by(Menu.sort).all()
    
    # 构建菜单树
    menu_tree = build_menu_tree(menus)
    
    return jsonify({'code': 0, 'message': '获取成功', 'data': menu_tree})


@admin_blueprint.route('/menus/<int:menu_id>', methods=['GET'])
@jwt_required()
def get_menu(menu_id):
    """获取菜单详情"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    menu = Menu.query.get(menu_id)
    if not menu:
        return jsonify({'code': 1, 'message': '菜单不存在'}), 404
    
    return jsonify({
        'code': 0, 
        'message': '获取成功', 
        'data': menu.to_dict()
    })


@admin_blueprint.route('/menus', methods=['POST'])
@jwt_required()
def create_menu():
    """创建菜单"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()
    
    # 测试账号不能创建菜单
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能创建菜单'}), 403
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    data = request.json
    title = data.get('title')
    path = data.get('path')
    component = data.get('component')
    icon = data.get('icon')
    permission = data.get('permission')
    sort = data.get('sort', 0)
    hidden = data.get('hidden', False)
    parent_id = data.get('parent_id')
    
    if not title:
        return jsonify({'code': 1, 'message': '菜单名称不能为空'}), 400
    
    # 如果有父菜单，检查父菜单是否存在
    if parent_id:
        parent_menu = Menu.query.get(parent_id)
        if not parent_menu:
            return jsonify({'code': 1, 'message': '父菜单不存在'}), 400
    
    try:
        # 创建新菜单
        menu = Menu(
            title=title,
            path=path,
            component=component,
            icon=icon,
            permission=permission,
            sort=sort,
            hidden=hidden,
            parent_id=parent_id
        )
        db.session.add(menu)
        
        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='创建菜单',
            ip=request.remote_addr,
            details=f'创建菜单 {title}'
        )
        db.session.add(log)
        
        db.session.commit()
        
        return jsonify({
            'code': 0, 
            'message': '创建成功', 
            'data': {'id': menu.id}
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'message': f'创建失败: {str(e)}'}), 500


@admin_blueprint.route('/menus/<int:menu_id>', methods=['PUT'])
@jwt_required()
def update_menu(menu_id):
    """更新菜单"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()
    
    # 测试账号不能更新菜单
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能更新菜单'}), 403
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    menu = Menu.query.get(menu_id)
    if not menu:
        return jsonify({'code': 1, 'message': '菜单不存在'}), 404
    
    data = request.json
    title = data.get('title')
    path = data.get('path')
    component = data.get('component')
    icon = data.get('icon')
    permission = data.get('permission')
    sort = data.get('sort')
    hidden = data.get('hidden')
    parent_id = data.get('parent_id')
    
    if not title:
        return jsonify({'code': 1, 'message': '菜单名称不能为空'}), 400
    
    # 检查是否将菜单设为自己的子菜单（循环引用）
    if parent_id and parent_id == menu_id:
        return jsonify({'code': 1, 'message': '不能将菜单设为自己的子菜单'}), 400
    
    # 如果有父菜单，检查父菜单是否存在
    if parent_id:
        parent_menu = Menu.query.get(parent_id)
        if not parent_menu:
            return jsonify({'code': 1, 'message': '父菜单不存在'}), 400
    
    try:
        # 更新菜单信息
        menu.title = title
        menu.path = path
        menu.component = component
        menu.icon = icon
        menu.permission = permission
        if sort is not None:
            menu.sort = sort
        if hidden is not None:
            menu.hidden = hidden
        menu.parent_id = parent_id
        
        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='更新菜单',
            ip=request.remote_addr,
            details=f'更新菜单 {title}'
        )
        db.session.add(log)
        
        db.session.commit()
        
        return jsonify({'code': 0, 'message': '更新成功'})
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'message': f'更新失败: {str(e)}'}), 500


@admin_blueprint.route('/menus/<int:menu_id>', methods=['DELETE'])
@jwt_required()
def delete_menu(menu_id):
    """删除菜单"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()
    
    # 测试账号不能删除菜单
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能删除菜单'}), 403
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    menu = Menu.query.get(menu_id)
    if not menu:
        return jsonify({'code': 1, 'message': '菜单不存在'}), 404
    
    # 检查菜单是否有子菜单
    if menu.children.count() > 0:
        return jsonify({'code': 1, 'message': '该菜单有子菜单，请先删除子菜单'}), 400
    
    try:
        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='删除菜单',
            ip=request.remote_addr,
            details=f'删除菜单 {menu.title}'
        )
        db.session.add(log)
        
        # 删除菜单
        db.session.delete(menu)
        db.session.commit()
        
        return jsonify({'code': 0, 'message': '删除成功'})
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'message': f'删除失败: {str(e)}'}), 500


@admin_blueprint.route('/user-menus', methods=['GET'])
@jwt_required()
def get_user_menus():
    """获取当前用户可访问的菜单"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    
    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404
    
    # 获取所有菜单并按照排序字段排序
    all_menus = Menu.query.order_by(Menu.sort).all()
    
    # 如果是超级管理员，返回所有菜单
    if admin.is_super:
        menu_tree = build_menu_tree(all_menus)
        return jsonify({'code': 0, 'message': '获取成功', 'data': menu_tree})
    
    # 如果是测试账号，返回所有菜单
    if admin.is_test:
        menu_tree = build_menu_tree(all_menus)
        return jsonify({'code': 0, 'message': '获取成功', 'data': menu_tree})
    
    # 获取用户拥有的权限
    user_permissions = admin.get_permissions()
    
    # 过滤出用户有权限访问的菜单
    accessible_menus = []
    for menu in all_menus:
        if not menu.permission or menu.permission in user_permissions:
            accessible_menus.append(menu)
    
    # 构建菜单树
    menu_tree = build_menu_tree(accessible_menus)
    
    return jsonify({'code': 0, 'message': '获取成功', 'data': menu_tree}) 